# -*- coding: utf-8 -*-

# Copyright 2009 David Lee Miller
#
# This file is part of POSSM (Python Open Source Scanning Microscopy).
#
# POSSM is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# POSSM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License         
# along with POSSM.  If not, see <http://www.gnu.org/licenses/>.
#                                                                           
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

#Global attributes are given in the form:
#ATTRIBUTE = (default value,unit,tree name,description,cell display)

#Cell display: 'XXX'
#first digit:
# 0 = normal
# 1 = read-only
#
#second digit:
# 0 = white
# 1 = light blue
# 2 = light green


ID = ('N/A','','ID','A generic field that is used to assign a sample ID.','020')
NOTES = ('N/A','','Notes','A generic field that can be used to add notes before starting a scan.','020')
NAME = ('scan 1','','name','A generic field for assigning a name to a scan','020')
SAMPLE_BIAS = (3.0,'volts','sample bias','The voltage that gets set to the sample prior to scan','000')
N_READS = (1,'','n reads','The number of times the measurement card reads at a given spot. Multiple reads are averaged together.','000')
SCAN_DELAY = (500,'ms','scan delay','The amount of time to delay before starting a scan.','000')
LINE_DELAY = (50,'ms','line delay','The wait time in ms to wait after a line has been scanned (either forward or back).','000')
POINT_DELAY = (50,'us','point delay','The wait time in 1 us intervals to delay before reading a point.','000')
ACCEL_WIDTH = (0,'dac steps','accel width','The width of curvature in sinusoidal scan rate.','000')
ACCEL_CURVE = (1,'','curvature','Refers to the amount of bending in the scan rate.','000')
TOP_DOWN = (0,'y/n','top down','Mark 1 for a top-down image. 0 Scans the image from the bottom up.','000')
SCAN_Y = (150,'pixels','scan y','Number of pixels in the y dimension.','000')
SCAN_X = (150,'pixels','scan x','Number of pixels in the x dimension.','000')
PHYS_X = (0.0,'angstroms','phys x','Physical size of the image in the x direction.','110')
PHYS_Y = (0.0,'angstroms','phys y','Physical size of the image in the y direction.','110')
PHYS_STEP = (0.0,'angstroms','phys step','Physical step size.','110')
SCAN_RATE = (0.0,'ang/s','scan rate','The average scan rate. period.','110')
EST_TIME = (0.0,'mins','est time','The estimate time to completion.','110')
MAX_RATE = (1000.0,'ang/s','max rate','The max scan rate. If higher than setting in worldsettings file, will not be used.','000')
DAC_STEP = (1,'','dac step','Step size in dac units. The fundamental unit of voltage step.','000')
DAC_AVGS = (1,'','dac avgs','The number of points to average (i.e. a pixel at at dac steps and 4 dac avgs represents 8 total dac units in resolution.','000')
#DO_IV = (0,'','do iv?','Toggles IV mode on or off')
IV_START = (5.0,'volts','start volts','Sets the max voltage of the IV scan.','000')
IV_END = (-5.0,'volts','end volts','Sets the min voltage of the IV scan.','000')
IV_LIM = (0,'y/n','limit I?','Keeps the current from saturating by stopping the bias output from increasing.','100')
I_MAX = (9.0,'volts','I Max','The value to stop the IV at when sweeping through the biases.','000')
I_MIN = (-9.0,'volts','I Min','The value to stop the IV at when sweeping through the biases.','000')
IV_READS = (10,'','n reads','Number of reads taken at each step in the IV scan.','000')
IV_DELAY = (25,'x4 us','delay','Delay time after sample voltage is changed to the next step voltage.','000')
IV_PREDELAY = (50,'x4 us','pre delay','Delay time after tip has been moved to a new position, but before the start of the IV layer.','000')
IV_SETDELAY = (50,'x4 us','set delay','Delay time immediately after the hold has been set.','000')
IV_MIDDELAY = (25,'x4 us','mid delay','Delay after the forward data is taken, but before the reverse data is taken.','000')
IV_POSTDELAY = (50,'x4 us','post delay','Delay after the IV scan has completed and the hold has been released.','000')
IV_STEPS = (200,'','steps','Number of steps in each direction of the IV scan.','000')
IV_Z = [[0.,'angstroms','z0','','000'],[-0.1,'angstroms','z1','','000'],[-0.2,'angstroms','z2','','000'],[-0.3,'angstroms','z3','','000'],[-0.4,'angstroms','z4','','000'],[-0.5,'angstroms','z5','','000'],[-0.6,'angstroms','z6','','000'],[-0.7,'angstroms','z7','','000'],[-0.8,'angstroms','z8','','000']]
IV_MULTIZ = (0,'','multi-z?','Number of steps to take after the first position has been taken.','000')
IV_RMPSTP = (10,'','ramp step','Number of voltage steps to take between iv values. A value of zero takes a step at every dac unit.','100')
RAMP_HZ = (10000,'hz','ramp hz','Update frequency of the ramp rate.','100')
GRIDX = (5,'pixels','grid x','Spacing between IV points in the x-direction','000')
GRIDY = (5,'pixels','grid y','Spacing between IV points in the y-direction','000')
STARTX = (0,'%','start x','Starting position for setting up IVs prior to scanning','000')
STARTY = (0,'%','start y','Starting position for setting up IVs prior to scanning','000')
ENDX = (100,'%','end x','Ending position for setting up IVs prior to scanning','000')
ENDY = (100,'%','end y','Ending position for setting up IVs prior to scanning','000')
CHECKER = (1,'y/n','checker','Staggers the IV positions so like a checkers board.','000')
XOFF = (0.0,'angstroms','x off','Sets the position of the x offset.','000')
YOFF = (0.0,'angstroms','y off','Sets the position of the y offset.','000')
ZRELATIVE = (0.0,'angstroms','z off','Sets the relative position of the z offset to the automatically zeroed position. Negative pulls the tip away from the sample.','000')
AUTOZ = (0,'y/n','auto z','Automatically sets the z offset so that the servo is in the sweet spot of its sensitivity range.','000')
GAIN_XHV = (1.0,'gain','xhv gain','Gain of the x-high voltage.','000')
GAIN_YHV = (1.0,'gain','yhv gain','Gain of the y-high voltage.','000')
GAIN_ZHV = (1.0,'gain','zhv gain','Gain of the z-high voltage.','000')
GAIN_ZOUT = (0.0,'dial','z out','Gain of z out.','020')
GAIN_SERVO = (1.0,'','servo gain','Gain of the servo.','020')
CURR_SENS = (0.0,'A/V','curr sens','I don\'t really know what this is','020')
CURR_RISE = (0.0,'A/V','curr rise','uh yeah','020')
VOLT_GAIN = (0.0,'','volt gain','','020')
VOLT_FILTER = (0.0,'kHz','volt filter','','020')
IZ_READS = (10,'','n reads','Number of reads taken during IZ scans.','000')
IZ_DELAY = (300,'x4 us','delay','Delay time before taking a read','000')
IZ_SETDELAY = (50,'x4 us','set delay','Delay time after the hold has been placed before the scan.','000')
IZ_POSTDELAY = (50,'x4 us','post delay','The wait time in 4 us intervals to delay after the scan.','000')
IZ_START = (0.0,'angstroms','start','Starting z offset for the IZ scan.','000')
IZ_END = (-1.0,'angstroms','end','Ending z offset for the IZ scan.','000')
IZ_STEPS = (100,'','steps','Number of steps to take.','000')
ZV_READS = (100,'','n reads','Number of reads taken during ZV scans.','000')
ZV_DELAY = (500,'x4 us','delay','Delay time before taking a read','000')
ZV_PREDELAY = (50,'x4 us','pre delay','Delay time after bias has been changed and before the scan starts.','000')
ZV_MIDDELAY = (100,'x4 us','mid delay','Delay time after the hold has been placed before the scan.','000')
ZV_POSTDELAY = (10,'x4 us','post delay','The wait time in 4 us intervals to delay after bias has been set back and scan is complete.','000')
ZV_START = (0.3,'volts','start volts','Sets the max voltage of the ZV scan.','000')
ZV_END = (10.0,'volts','end volts','Sets the min voltage of the ZV scan.','000')
ZV_STEPS = (200,'','steps','Number of steps to take.','000')
N_BIAS_STEPS = (0,'nsteps','multi-bias?','Number of steps to take after the first bias has been taken.','000')
BIAS_STEPS = [[0.0,'volts','step0','','000'],[0.0,'volts','step1','','000'],[0.0,'volts','step2','','000'],[0.0,'volts','step3','','000'],[0.0,'volts','step4','','000'],[0.0,'volts','step5','','000'],[0.0,'volts','step6','','000'],[0.0,'volts','step7','','000'],[0.0,'volts','step8','','000']]
CB_MAX = (9.0,'volts','max','The maximum voltage for blasting crap.','000')
CB_MIN = (-9.0,'volts','min','The minimum voltage for blasting crap.','000')
CB_FREQ = (1e1,'Hz','frequency','The frequency at which to oscillate the tip.','000')
STORAGE_SERVER = ('betty','','server','The network name of the computer where data is stored','000')
RSYNC_FLAGS = ('auv','','flags','Any desired flags to send with rsync','000')
REMOTE_PATH = ('/home/stmb/rawdata','','rpath','The path to the data directory on the remote server.','000')
SSH_USER = ('stmb','','user','The ssh user used to establish the connection.','000')

class Menus(object):
	'''
	A class to organize and arrange the menus for the wx grid widget. If a new menu
	is needed, define it here.
	
	'''
	MENU = {}
	MENU['Sample Information'] = [ID,NOTES,NAME]
	MENU['Image Parameters'] = [SAMPLE_BIAS,N_READS,SCAN_DELAY,LINE_DELAY,POINT_DELAY,ACCEL_WIDTH,ACCEL_CURVE,TOP_DOWN]
	MENU['Image Size'] = [SCAN_Y,SCAN_X,DAC_STEP,DAC_AVGS,MAX_RATE,PHYS_Y,PHYS_X,PHYS_STEP,SCAN_RATE,EST_TIME]
	MENU['IV Parameters'] = [IV_START,IV_END,IV_READS,IV_STEPS,IV_RMPSTP,RAMP_HZ,IV_LIM,I_MAX,I_MIN]
	MENU['IV Delays'] = [IV_DELAY,IV_PREDELAY,IV_SETDELAY,IV_MIDDELAY,IV_POSTDELAY]
	MENU['Multi-Z IV'] = [IV_MULTIZ,IV_Z[0],IV_Z[1],IV_Z[2],IV_Z[3],IV_Z[4],IV_Z[5],IV_Z[6],IV_Z[7],IV_Z[8]]
	MENU['Spectroscopy Locations'] = [GRIDX,GRIDY,STARTX,STARTY,ENDX,ENDY,CHECKER]
	MENU['Offsets'] = [XOFF,YOFF,AUTOZ,ZRELATIVE]
	MENU['Gains'] = [GAIN_XHV,GAIN_YHV,GAIN_ZHV,GAIN_ZOUT,GAIN_SERVO,CURR_SENS,CURR_RISE,VOLT_GAIN,VOLT_FILTER]
	MENU['Multiple Bias'] = [N_BIAS_STEPS,BIAS_STEPS[0],BIAS_STEPS[1],BIAS_STEPS[2],BIAS_STEPS[3],BIAS_STEPS[4],\
	BIAS_STEPS[5],BIAS_STEPS[6],BIAS_STEPS[7],BIAS_STEPS[8]]
	MENU['IZ Parameters'] = [IZ_START,IZ_END,IZ_STEPS,IZ_READS]
	MENU['IZ Delays'] = [IZ_DELAY,IZ_SETDELAY,IZ_POSTDELAY]
	MENU['ZV Parameters'] = [ZV_START,ZV_END,ZV_STEPS,ZV_READS]
	MENU['ZV Delays'] = [ZV_DELAY,ZV_PREDELAY,ZV_MIDDELAY,ZV_POSTDELAY]
	MENU['Bias'] = [SAMPLE_BIAS]
	MENU['Blast Parameters'] = [CB_MAX,CB_MIN,CB_FREQ]
	MENU['Storage Options'] = [SSH_USER,STORAGE_SERVER,RSYNC_FLAGS,REMOTE_PATH]
	
	def _getMenu(self,name,loc):
		'''
		Takes the requested menu and returns all of the values in each
		location (loc) as a list.
		
		Keyword Arguments:
		name -- a string. the name of the menu element desired.
		loc -- the location of the data type
		
		'''
		menu = []
		for ele in self.MENU[name]:
			menu.append(ele[loc])
		return menu
	
	def _fullMenu(self,branches,loc):
		'''
		Takes all the branches given and makes a full menu from them for
		a certain data type.
		
		'''
		fullmenu = []
		for branch in branches:
			fullmenu.append(self._getMenu(branch,loc))
		return fullmenu
